Fork me on GitHub

Spring 源码解析

注意:所有文章除特别说明外,转载请注明出处.

Spring 源码解析

IOC

(Inversion of Control):控制反转

控制:资源的获取方式

​ 主动式:(要什么资源自给创建即可)

1
2
3
4
5
6
7
​	BookServlet{

​ BookService bs = new BookService();

​ AirPlane ap = new AirPlane();//复杂对象的创建是一个比较庞大的工程

​ }

被动式:资源的获取不是我们自己创建,而是交给容器来管理,创建和设置。

1
2
3
4
5
6
BookServlet{
BookService bs ;
public void test(){
bs.checkout();//
}
}

容器:管理所有得组件(有功能的类),假设BookServlet受容器管理,BookService也是受容器管理的;

那么容器可以自动探查出那些组件(类)需要用到另一个组件,容器帮我们创建BookService对象,并赋值。

==容器:主动获取变为自动接收。==

DI

(Dependency Injection)依赖注入:

​ 容器可以知道那个组件(类)运行的时候,需要另一个类(组件);容器通过反射的方式,将容器中准备好的BookService对象注入(利用反射给对象赋值)到BookServlet之中,

只要容器管理的组件,都能使用容器强大的功能;

Helloword(通过各种方式给容器中注册对象)

以前都是自己New对象,现在所有对象交给容器来创建;==给容器注册组件==

框架编写流程:

1)、导包

​ 核心容器:

​ beans,context,core,expression,

​ 日志包:

​ commons-logging

2)、写配置

​ spring的配置文件中,集合了spring的IOC容器管理的所有组件(会员清单);

​ 创建一个 Spring Bean Configuration的配置文件

​ 一个Bean标签可以注册一个组件

1
2
3
4
5
6
7
8
9
10
class :要写注册的全类名
id: 这个对象的唯一标示
property标签:为属性赋值
name:属性名
val:属性值

//获取属性
//ApplicationContext IOC 容器
ApplicationContext ioc = new ClassPathXMlApplicationContext("ioc.xml");
getbean 获取

3)、测试

Resource 和 Autowried 的区别与联系

联系:

都是用来装配Bean的注解。都可以写在字段上,或写在setter方法上。

区别:

Autowried:

默认情况下要求对象必须存在, 它要求依赖对象必须存在. 若允许null值, 可以设置它的==required为false.==(默认为true)

默认按照类型进行装配注入. 如果想按照名称进行装配的话, 需要与Qualifer注解搭配使用.

1
2
3
@Autowried
@Qualifier("admin") //按照名称装配
private AdminDAO adminDAO;

Autowried更加强大,==它是Spring提供的注解==。

Resource:

默认按照名称来装配注入, 只有找不到与名称匹配的bean才会按照类型来注入.

Resource 的装配顺序
  • 如果同时指定了name属性和type属性, 那么Spring将从容器中找唯一匹配的bean进行装配, 找不到则抛出异常
  • 如果指定了name属性值, 则从容器中查找名称匹配的bean进行装配, 找不到则抛出异常
  • 如果指定了type属性值, 则从容器中查找类型匹配的唯一的bean进行装配, ==找不到或者找到多个都会抛出异常==
  • 如果都不指定, 则会自动按照byName方式进行装配, 如果没有匹配, 则回退一个按照类型进行匹配, 如果匹配则自动装配

@Rescource :扩展性更强,即使更换另外一个框架,他也可以用。

IOC 总结:

  1. ioc是一个容器,帮我们管理所有组件
  2. 依赖注入:@Autowired:自动赋值
  3. 某个组件要使用Spring提供的更多(IOC,AOP),==必须注册到容器中。==

体会:

1. 容器启动,默认会创建所有单实例Bean
2. autowired 自动装配,是从容器中找到这些符合要求的bean
3. ioc.getBean(); 也是从容器中找到这个bean
4. 容器中包括了所有的Bean
5. 调试Spring 的源码 看看容器到底是什么。==其实就是一个map==
6. 这个map保存好了所有创建好的bean,并提供外界获取的功能。。。
7. 探索一下单实例bean到保存在了那个map中。源码部分

如何看框架源码:

1. 从HelloWord 开始 Debug 模式
2. 翻译方法名
3. 放行这个方法,观察控制台,以及变量的变化
4. 看方法上面的注释。

==起名一定要规范,注释一定要清楚==

AOP

​ AOP:面向切面编程,指在程序运行期间,将某段代码==动态的切入==到指定方法的指定位置进行运行的这种编程方式,称为面向切面编程

​ 场景:计算器运行计算方法的时候,进行日志记录

加日志记录:

​ 1)、直接编写在方法内部,不推荐,修改特别麻烦

​ 日志记录:系统的辅助功能

​ 业务逻辑:主要功能

​ 耦合

​ 2)、我们希望的是:

​ 业务逻辑:(核心功能);日志模块;在核心功能运行时,自己动态的加上。

​ 运行的时候,日志功能可以自动加上

Spring动态代理难:Spring实现了AOP功能,底层就是动态代理:

​ 可以利用Spring一句代码都不写的去创建动态代理:

​ 实现简单,而且没有强制要求对象那个必须实现接口。

​ 将某段代码==动态的切入==到指定方法的指定位置进行运行的这种编程方式(Spring简化了面向切面编程)

五个注解通知

  1. @Before 在目标方法之前运行。 前置通知

  2. @After 在目标方法之后运行 后置通知

  3. @AfterReturning:在目标方法正常返回之后运行 返回通知

  4. @AfterThrowing:在目标方法抛出异常之后运行 异常通知

  5. @Around : ==环绕通知==

    执行顺序:

    正常执行:@Before(前置) –> @After(后置)–>@AfterReturning(正常返回)

    异常执行:@Before(前置) –> @After(后置)–>@AfterThrowing(方法异常)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
try{
//前置通知
method.invoke(obj,args);
//返回通知
}catch(e){
//异常通知
}finally{
//后置通知
}
Spring中最强大的通知
四合一通知:环绕通知
环绕通知中有一个参数,ProceedingJoinPoint pjp
//利用反射调用方法,就等同于method.invoke(obj,args);
pjp.proceed(args);

public Object myAround() throws Throwable{
//获取参数
Object args = pjp.getArgs();
//获取方法名
String name = pjp.getSignature().getName();
Object proceed = null;
try{
//前置通知@Before
System.out.println("【环绕前置通知】【"+name+"方法开始了】");
//利用反射调用方法,就等同于method.invoke(obj,args);

proeed = pjp.proceed(args);

//返回通知@AfterReturning
System.out.println("【环绕返回通知】【"+name+"方法返回,返回值"+proceed+"】");
}catch(e){
//异常通知@AfterThrowing
System.out.println("【环绕异常通知】【"+name+"方法出现异常,异常信息为:】"+e+"】");
//为了能让外界感知到这个异常我们一定将异常抛出去
throw new RuntimeException(e);
}finally{
System.out.println("【环绕后置通知】【"+name+"方法结束了】");
//后置通知@After
}
//反射调用的返回值也一定返回出去
return proceed;
}

==环绕通知是优先于普通通知执行的!!!==
执行顺序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
​	【普通前置】

{

try{

​ 环绕前置

​ 环绕执行,目标方法执行

​ 环绕返回

​ }catch(e){

​ 环绕异常(一定要抛出去)

​ }finally{

​ 环绕返回

​ }

}

​ 【普通后置】

​ 【普通方法返回/异常】

新的顺序:

​ ==环绕前置—–普通前置—-目标方法执行——环绕正常返回/出现环绕异常——环绕后置—-普通后置—–普通返回或者异常==

动态代理

​JDK代理:

java代理类的实现主要靠Proxy类和InvocationHandler接口来实现。

  1. 通过Proxy.getProxyClass()方法生成代理类的class文件并加载。(具体生成步骤见 源码中ProxyClassFactory.apply()
  2. 获取这个class的构造器,传入代理类的逻辑实现类InvocationHandler作为构造函数参数,实例化class获得代理类对象。
  3. 调用代理类对象的对应方法
CGlib代理:

Spring 源码核心

AOP源码核心:

​ AOP源码:就是动态代理,套动态代理,【看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么】

1.什么是EnableAspectJAutoProxy

​ 1.@Import(AspectJAutoProxyRegistrar.class):给容器中导入这个类,AspectJAutoProxyRegistrar

​ 利用AspectJAutoProxyRegistrar 给容器中自定义注册bean

​ internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreator

​ 给容器中注册一个AnnotationAwareAspectJAutoProxyCreator

2.AnnotationAwareAspectJAutoProxyCreator

​ AnnotationAwareAspectJAutoProxyCreator

​ -》父类:AspectJAwareAdvisorAutoProxyCreator

​ -》父类:AbstractAdvisorAutoProxyCreator

​ -》父类:AbstractAutoProxyCreator

​ implements SmartInstantiationAwareBeanPostProcessor,, BeanFactoryAware

​ 关注后置处理器(在bean初始化完成前后做的事情)、自动装配BeanFactory

​ AbstractAutoProxyCreator.setBeanFactory(BeanFactory beanFactory)

​ AbstractAutoProxyCreator.中有后置处理器

3.流程

​ 1)传入配置类,创建IOC容器

​ 2)注册配置类,调用refresh(),刷新容器

​ 3)registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建

​ 1.先获取IOC容器中已经定义的需要的创建对象的所有BeanPostProcessor

​ 2.给容器中加入别的BeanPostProcessor

​ 3.优先注册实现了PriorityOrdered 接口的BeanPostProcessor

​ 4.再给容器中注册了实现了Ordered接口的BeanPostProcessor

​ 5.注册没有实现优先级接口的BeanPostProcessor

​ 6.注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器之中

​ 创建 internalAutoProxyCreator 的

​ BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】

​ 1)创建Bean的实例

​ 2)populateBean,给Bean的属性赋值

​ 3)initializeBean 初始化Bean

​ 还有很多 实在是看不懂了

AOP源码总结:

  1. @EnableAspectJAutoProxy 开启AOP功能

  2. EnableAspectJAutoProxy 会给容器中注册一个AnnotationAwareAspectJAutoProxyCreator

  3. AnnotationAwareAspectJAutoProxyCreator 是一个后置处理器

  4. 容器的创建流程

     1.    registerBeanPostProcessors() 注册后置处理器,创建AnnotationAwareAspectJAutoProxyCreator对象
        2.    finishBeanFactoryInitialization() 初始化剩下的单实例bean
    1. 创建业务逻辑组件和切面组件
    2. AnnotationAwareAspectJAutoProxyCreator 拦截组件的创建过程
    3. 组件创建完成之后,判断组件是否需要增强
       1. 是,切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(Cglib)。
    
  5. 执行目标方法:

    1. 代理对象执行目标方法
         2. CglibAopProxy.intercept();
             1. 得到目标方法的拦截器链,(增强器包装成拦截器MethodInterceptor)
                 2. 利用拦截器的链式机制,一次进入每一个拦截器进行执行
    
    1. 效果:

      ​ 正常执行:前置通知——》目标方法——》后置通知——》返回通知

      ​ 异常执行:前置通知——》目标方法——》后置通知——》异常通知

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
LogAspectProxy{
try{
@Before
method.invoke(obj,args);
BAspectProxy{
@Before
method.invoke(obj,args);
@AfterReturning
//..........
//修改了返回值
}

@AfterReturning
}catch(e){
@AfterThrowing
}finally{
@After
}
}

第一个切面的环绕通知,==不会影响第二个切面==。但是如果第二个切面==修改了返回值,第一个切面感知到的返回值就不同了==。

IOC源码核心!!!:

IOC:

1. IOC是一个容器?用什么装的?
2. 默认容器启动时,创建所有单实例对象
3. 我们可以直接从容器中获取到这个对象

SpringIOC:

1. IOC容器的启动过程,启动期间都做了什么(**什么时候创建了单实例bean**)
2. IOC是如何创建这些单实例bean,并且是如何管理的?
3. 这些单实例bean都保存在了哪里?

思路:

​ 从HelloWord开始,调试每个方法的作用!!

1.ClassPathXmlApplicationContext 构造器!

ApplicationContext ioc = new ClassPathXmlApplicationContext(“applicationContext.xml”);

==this(new String[] {configLocation}, true, null);==

1
2
3
4
5
6
7
8
9
10
11
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {

super(parent);
setConfigLocations(configLocations);
if (refresh) {
//对象创建,所有单实例bean创建完成
refresh();
}
}

2.Refresh()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
@Override
public void refresh() throws BeansException, IllegalStateException {
//同步锁保证IOC容器只会被创建一次
synchronized (this.startupShutdownMonitor) {
// 准备容器刷新
prepareRefresh();

// 准备了一个Bean工厂,并解析XML文件,将所有的配置信息保存起来
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 准备Bean工厂
prepareBeanFactory(beanFactory);

try {
postProcessBeanFactory(beanFactory);

invokeBeanFactoryPostProcessors(beanFactory);

//注册Bean工厂的后置处理器
registerBeanPostProcessors(beanFactory);

//初始化消息源,支持国际化功能
initMessageSource();

// 初始化事件转换器
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
//初始化其他的 beans 在我们的子类中 留给子类重写用的
onRefresh();

// Check for listener beans and register them.
//注册一些监听器
registerListeners();

//***********************************************
// Instantiate all remaining (non-lazy-init) singletons.

//初始化所有单实例bean的地方
finishBeanFactoryInitialization(beanFactory);

//***********************************************



// Last step: publish corresponding event.
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}

3.finishBeanFactoryInitialization(beanFactory)实现;

​ ==AbstractApplicationContext== 类下面的 ;Bean工厂;创建bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}

// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}

// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}

// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);

// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();


//***********************************************
// Instantiate all remaining (non-lazy-init) singletons.
//初始化所有单实例bean的地方
beanFactory.preInstantiateSingletons();
//***********************************************
}

4.preInstantiateSingletons方法

​ ==DefaultListableBeanFactory==类下面的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}

// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.


//***********************************************
//拿到所有的要创建的bean的名称
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...
//按顺序创建bean
for (String beanName : beanNames) {
//根据bean的id 获取到bean的定义信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//判断创建非抽象的的,单实例的,非懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断是否是一个实现了Factory接口的bean
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//创建bean的细节
getBean(beanName);
}
}
}

// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

getBean(beanName);创建bean的细节

其实都是调用了==doGetBean(name, null, null, false)==方法

1
2
3
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}

doGetBean(name, null, null, false);幕后主谋

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    @SuppressWarnings("unchecked")
    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
    @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    //先从已经注册的所有单实例bean中找,看有没有那个bean 第一次创建是没有的
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
    if (logger.isDebugEnabled()) {
    if (isSingletonCurrentlyInCreation(beanName)) {
    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
    "' that is not fully initialized yet - a consequence of a circular reference");
    }
    else {
    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
    }
    }
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
    // Fail if we're already creating this bean instance:
    // We're assumably within a circular reference.
    if (isPrototypeCurrentlyInCreation(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
    }

    // Check if bean definition exists in this factory.
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    // Not found -> check parent.
    String nameToLookup = originalBeanName(name);
    if (parentBeanFactory instanceof AbstractBeanFactory) {
    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
    nameToLookup, requiredType, args, typeCheckOnly);
    }
    else if (args != null) {
    // Delegation to parent with explicit args.
    return (T) parentBeanFactory.getBean(nameToLookup, args);
    }
    else {
    // No args -> delegate to standard getBean method.
    return parentBeanFactory.getBean(nameToLookup, requiredType);
    }
    }

    //标志这个bean已经被创建了
    if (!typeCheckOnly) {
    markBeanAsCreated(beanName);
    }

    try {
    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    checkMergedBeanDefinition(mbd, beanName, args);

    // Guarantee initialization of beans that the current bean depends on.
    //拿到创建当前bean之前所依赖的,需要提前创建的bean depend-on属性
    //如果有就循环创建
    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) {
    for (String dep : dependsOn) {
    if (isDependent(beanName, dep)) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
    }
    registerDependentBean(dep, beanName);
    try {
    getBean(dep);
    }
    catch (NoSuchBeanDefinitionException ex) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
    }
    }
    }

    // Create bean instance.创建bean实例
    if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, () -> {
    try {
    return createBean(beanName, mbd, args);
    }
    catch (BeansException ex) {
    // Explicitly remove instance from singleton cache: It might have been put there
    // eagerly by the creation process, to allow for circular reference resolution.
    // Also remove any beans that received a temporary reference to the bean.
    destroySingleton(beanName);
    throw ex;
    }
    });
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

    else if (mbd.isPrototype()) {
    // It's a prototype -> create a new instance.
    Object prototypeInstance = null;
    try {
    beforePrototypeCreation(beanName);
    prototypeInstance = createBean(beanName, mbd, args);
    }
    finally {
    afterPrototypeCreation(beanName);
    }
    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    }

    else {
    String scopeName = mbd.getScope();
    final Scope scope = this.scopes.get(scopeName);
    if (scope == null) {
    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    }
    try {
    Object scopedInstance = scope.get(beanName, () -> {
    beforePrototypeCreation(beanName);
    try {
    return createBean(beanName, mbd, args);
    }
    finally {
    afterPrototypeCreation(beanName);
    }
    });
    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    }
    catch (IllegalStateException ex) {
    throw new BeanCreationException(beanName,
    "Scope '" + scopeName + "' is not active for the current thread; consider " +
    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
    ex);
    }
    }
    }
    catch (BeansException ex) {
    cleanupAfterBeanCreationFailure(beanName);
    throw ex;
    }
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && !requiredType.isInstance(bean)) {
    try {
    T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
    if (convertedBean == null) {
    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }
    return convertedBean;
    }
    catch (TypeMismatchException ex) {
    if (logger.isDebugEnabled()) {
    logger.debug("Failed to convert bean '" + name + "' to required type '" +
    ClassUtils.getQualifiedName(requiredType) + "'", ex);
    }
    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    }
    }
    return (T) bean;
    }

5.getSingleton方法

==DefaultSingletonBeanRegistry==类下面的

1
2
3
4
/** Cache of singleton objects: bean name --> bean instance
按照名字和 实例 缓存所有对象
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
//先从一个地方将这个bean get出来
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//bean 创建 (千呼万唤始出来) 创建完成后调用添加单实例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
//添加创建的bean
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}

6.addSingleton

==添加进map(ConcurrentHashMap)==

IOC:容器之一,保存单实例bean的地方

==DefaultSingletonBeanRegistry—-singletonObjects==

1
2
3
4
5
6
7
8
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}

IOC流程源码总结!!!!!!!:

1)、ClassPathXmlApplicationContext 构造器 调用 Refresh()方法

2)、 Refresh()方法:

1. 加上同步锁保证IOC容器只会被创建一次
2. 准备了一个Bean工厂,并解析XML文件,将所有的配置信息保存起来
3. 注册Bean工厂的后置处理器,初始化消息源,(支持国际化功能),
4. 初始化一些事件转换器,注册一些监听器 
5. 初始化其他的  beans 在我们的子类中   留给子类重写用的 方法 **onRefresh();**
6.   ==finishBeanFactoryInitialization(beanFactory);  初始化单实例的地方。==

3)、finishBeanFactoryInitialization(beanFactory) 方法

1. AbstractApplicationContext 类下面的 ;Bean工厂;创建bean
2. 调用 beanFactory.preInstantiateSingletons();  初始化所有单实例bean的地方

4)、==preInstantiateSingletons();==

1. 拿到所有的要创建的bean的名称
2. 按顺序创建bean (for each循环)
3. 根据bean的id 获取到bean的定义信息
4. 判断创建非抽象的的,单实例的,非懒加载的
5. 创建bean的细节 (getBean方法)

5)、==getBean方法==

  1. 调用 doGetBean(name, null, null, false);

6)、==doGetBean==方法

1. 先从已经注册的所有单实例bean中找,看有没有那个bean ==第一次创建是没有的==
2. 判断拿到创建当前bean之前所依赖的,需要提前创建的bean   depend-on属性  (如果有就循环创建)
3.  调用:getSingleton(创建单实例bean)

7)、==getSingleton==方法

1. 先从容器将这个 bean  get出来(第一次创建没有)
2. bean 创建 (千呼万唤始出来) 创建完成后调用添加单实例
3. 添加创建的bean,addSingleton方法

8)、==addSingleton==方法

1. 用synchronized 加锁 将所有的对象添加进容器(singletonObjects)
         2. 单实例容器其实就是一个ConcurrentHashMap(256)

==getBean总结:==

  • 转换 BeanName
  • 从缓存中加载实例
  • 实例化 Bean
  • 检测依赖
  • 创建 Bean
  • 添加到 IOC 容器中

面试题:

BeanFactory和ApplicationContext 的区别:

  • ApplicationContext 是 BeanFactory的子接口;

  • BeanFactory :bean工厂接口,负责创建bean实例;容器里面的保存的所有单例bean其实是一个map,也是Spring 最底层的接口

  • ApplicationContext:是容器接口;更多的负责容器功能的实现;(可以基于BeanFactory创建好的对象之上完成强大的容器) 容器可以从map中获取这些bean,并且 aop,DI,实在ApplicationContext接口下的这些类里面。

  • ==BeanFactory :是Spring 最底层的接口; ApplicationContext:是留给我们程序员使用的IOC容器接口;ApplicationContext 是 BeanFactory 的子接口。==

  • ==Spring里面最大模式是工厂模式。==

    <bean class=""></bean> 类似于使用说明书

    BeanFactory:bean工厂;工厂模式。帮用户创建bean。

Spring Bean的作用域

  • singleton:默认作用域,容器里拥有唯一的Bean实例
  • prototype:针对每一个getBean请求,容器都会创建一个Bean实例
  • request:每个HTTP请求一个
  • session:每个session创建一个Bean
  • globalSession:每个全局的HTTP Session 创建一个Bean实例

Spring Bean 的生命周期

Bean的完整生命周期从 spring 容器开始实例化 bean 开始,到销毁。可以从三点来理解

  • 1、 bean自身的方法:包括构造方法、 set 方法、 init-method 指定的方法、 destroy-method 指定的方法

  • 2、 Bean级生命周期接口方法:如 BeanNameAware 、 BeanFactoryAware 等这些接口方法由 bean类实现。

  • 3、 容器级生命周期接口方法:有InstantiationAwareBeanPostProcessor 、 BeanPostProcessor 等。一般称为后置处理器他们一般不由bean 本身实现,独立存在,注册到 spring 容器中。 Spring 通过接口反射预先知道,当 spring 容器创建任何 bean 时,这些后处理器都会发生作用。

==Spring的传播机制==

  • 1.如果当前没有事务,就新建一个事务;如果已存在一个事务,就加入到这个事务中。
  • 2.支持当前事务,如果当前没有事务,以非事务方式执行。
  • 3.使用当前事务,如果当前没有事务,则抛出异常。
  • 4.新建事务,如果当前存在事务,则把当前事务挂起。
  • 5.以非事务方式执行,如果当前存在事务,则把当前事务挂起。
  • 6.以非事务方式执行,如果当前存在事务,则抛出异常。
  • 7.如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 1. 类似的操作。

Servlet如何处理多个请求访问?

  • Servlet容器默认是采用单实例多线程的方式处理多个请求的:

  • 1.当web服务器启动的时候(或客户端发送请求到服务器时),Servlet就被加载并实例化(只存在一个Servlet实例);

  • 2.容器初始化Servlet主要就是读取配置文件(可以通过servlet.xml的设置线程池中线程数目,初始化线程池通过web.xml,初始 化每个参数值等等。

  • 3.当请求到达时,Servlet容器通过调度线程(Dispatchaer Thread) 调度它管理下线程池中等待执行的线程(Worker Thread)给请求者;

  • 4.线程执行Servlet的service方法;

  • 5.请求结束,放回线程池,等待被调用;

(注意:避免使用实例变量(成员变量),因为如果存在成员变量,可能发生多线程同时访问该资源时,都来操作它,照成数据的不一致,因此产生线程安全问题)

本文标题:Spring 源码解析

文章作者:Bangjin-Hu

发布时间:2019年10月15日 - 09:22:26

最后更新:2020年03月30日 - 08:52:05

原始链接:http://bangjinhu.github.io/undefined/Spring 解析/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Bangjin-Hu wechat
欢迎扫码关注微信公众号,订阅我的微信公众号.
坚持原创技术分享,您的支持是我创作的动力.